import logging
import os
from django.conf import settings

from django.db.models import Q
from django.shortcuts import render
from django.utils import timezone
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from courses.models import Course, CourseExpire, CourseChapter
from courses.ser import CourseSerializer, CourseDetailSerializer, CourseChapterSerializer
from orders.models import OrderDetail
from utils.kafka_producer import send_kafka_message
from django_redis import get_redis_connection

logger = logging.getLogger("django")


# Create your views here.


class CoursePage(PageNumberPagination):
    # 默认每页显示数量
    page_size = 12
    page_query_param = 'page'
    page_size_query_param = 'page_size'
    max_page_size = 50

    def get_paginated_response(self, data):
        return Response({
            "code": 1,
            "message": "查询成功",
            "data": {
                'count': self.page.paginator.count,
                'next': self.get_next_link(),
                'previous': self.get_previous_link(),
                'results': data,
            }
        })


class CourseListAPIView(ListAPIView):
    """
    根据导航名称查询课程列表
    导航表(id,name)
    导航课程中间表(ID,课程ID,导航ID)
    课程表(id,name,........)
    """

    serializer_class = CourseSerializer
    pagination_class = CoursePage

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            # 发送搜索日志到Kafka
            try:
                nav_name = request.query_params.get("nav_name", "")
                category_id = request.query_params.get("categoryId", "")
                sort_ord = request.query_params.get("sortord", "")
                price_range = request.query_params.get("price_range", "")
                keywords = request.query_params.get("keywords", "")

                # keywords 支持数组：逗号或空白分隔时拆分
                keywords_value = keywords
                if isinstance(keywords, str) and ("," in keywords or " " in keywords):
                    keywords_splitted = [k.strip() for k in keywords.replace("\u3000", " ").replace("，", ",").split(",")]
                    keywords_splitted = sum([k.split() for k in keywords_splitted], [])
                    keywords_value = [k for k in (kw.strip() for kw in keywords_splitted) if k]

                sort_map = {
                    "1": "最新",
                    "2": "最热",
                    "3": "价格升序",
                }

                user_id = ""
                if getattr(request, "user", None) and request.user.is_authenticated:
                    user_id = str(request.user.id)
                else:
                    user_id = (
                        request.headers.get('X-Anonymous-Id')
                        or request.COOKIES.get('anonymous_id')
                        or request.GET.get('anonymous_id')
                        or ""
                    )

                result_ids = []
                try:
                    result_ids = [str(item.get('id')) for item in serializer.data if isinstance(item, dict) and item.get('id') is not None]
                except Exception:
                    result_ids = []

                search_log = {
                    "user_id": user_id or "",
                    "search_time": timezone.now().isoformat(),
                    "nav_name": nav_name or "",
                    "category": str(category_id) if category_id else "",
                    "keywords": keywords_value if keywords_value else "",
                    "sort_by": sort_map.get(str(sort_ord), ""),
                    "price_range": "" if not price_range else str(price_range),
                    "search_results": result_ids,
                }

                kafka_topic = getattr(settings, "KAFKA_SEARCH_TOPIC", os.getenv("KAFKA_SEARCH_TOPIC", "search_topic"))
                logger.info("[Producer] 准备发送搜索日志 topic=%s key=%s payload=%s", kafka_topic, user_id or None, search_log)
                send_kafka_message(topic=kafka_topic or "search_topic", key=user_id or None, value=search_log)
            except Exception as _e:
                logger.error(f"发送课程搜索日志失败: {_e}")

            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    def get_queryset(self):
        """
        重写查询方法
        :return: 根据导航名称筛选后的课程查询集
        """

        # 获取查询参数重的导航名称
        nav_name = self.request.query_params.get("nav_name", "")
        category_id = self.request.query_params.get("categoryId", "")
        sort_ord = self.request.query_params.get("sortord", "")  # 接受前端传递过来的排序方式
        price_range = self.request.query_params.get("price_range", "")  # 接受前端传递过来的价格区间
        keywords = self.request.query_params.get("keywords", "")  # 接受前端传递过来的关键词
        #logger.info(f"正在查询导航分类[{nav_name}],课程分类[{category_id}]下的课程信息")
        logger.info(f"正在查询导航分类[{nav_name}],课程分类[{category_id}]下的课程信息,排序方式[{sort_ord}],价格区间[{price_range}],关键词[{keywords}]")
        #
        # if not nav_name:
        #     logger.info("未提供导航名称参数,返回空数据")
        #     return Course.objects.none()

        try:

            # 构建基础数据
            query_set = Course.objects.filter(status=1)

            # 根据导航名称过滤
            if nav_name:
                logger.info(f"正在g根据导航分类[{nav_name}.过滤")
                query_set = query_set.filter(nav_relations__nav_category__name=nav_name)

            # 根据分类ID过滤
            if category_id and category_id != '0':
                logger.info(f"正在根据课程分类:[{category_id}]过滤")
                query_set = query_set.filter(categories__id=category_id)

            if price_range:
                logger.info(f"正在根据价格区间[{price_range}]过滤")
                if price_range == '1':  # 免费
                    query_set = query_set.filter(course_type=1)
                elif price_range == '2':  # 付费
                    query_set = query_set.filter(course_type=2)

            if keywords:
                logger.info(f"正在根据关键词[{keywords}]过滤")
                query_set = query_set.filter(
                    Q(name__icontains=keywords) | Q(brief__icontains=keywords) | Q(teacher__name__icontains=keywords))

                # 如果没有任何的过滤条件
            if not nav_name and not category_id and not price_range and not keywords:
                logger.info("未提供任何过滤条件,返回空数据")
                return Course.objects.none()

            order_filed = '-id'  # 默认排序字段

            if sort_ord:
                if sort_ord == '1':  # 最新
                    logger.info("正在按照最新排序")
                    order_filed = '-pub_date'
                if sort_ord == '2':  # 最热
                    logger.info("正在按照最热排序")
                    order_filed = '-students'
                if sort_ord == '3':  # 价格
                    logger.info("正在按照价格排序")
                    order_filed = 'price'

            # 优化查询
            query_set = query_set.select_related('teacher').order_by(order_filed).distinct()

            course_count = query_set.count()
            logger.info(f"查询到导航分类{nav_name}下的课程数量:{course_count}")

            return query_set

        except Exception as e:
            logger.error(f"查询课程列表发生异常:{str(e)}")
            return Course.objects.none()



class CourseDetailAPIView(RetrieveAPIView):
        queryset = Course.objects.filter(status=1,is_deleted=False)
        logger.info(f"正在查询课程详情:{queryset}")
        serializer_class = CourseDetailSerializer
        def retrieve(self, request, *args, **kwargs):
            try:
                instance = self.get_object()
                serializer = self.get_serializer(instance)
                logger.info(f"正在查询课程详情:{instance.name},id:{instance.id}")
                # 发送浏览日志到Kafka（字段缺失填空）
                try:
                    user_id = ""
                    if getattr(request, "user", None) and request.user.is_authenticated:
                        user_id = str(request.user.id)
                    else:
                        user_id = (
                            request.headers.get('X-Anonymous-Id')
                            or request.COOKIES.get('anonymous_id')
                            or request.GET.get('anonymous_id')
                            or ""
                        )

                    view_log = {
                        "user_id": user_id or "",
                        "course_id": str(getattr(instance, 'id', "") or ""),
                        "course_name": getattr(instance, 'name', "") or "",
                        "view_time": timezone.now().isoformat(),
                    }
                    kafka_topic = getattr(settings, "KAFKA_VIEW_TOPIC", os.getenv("KAFKA_VIEW_TOPIC", "view_topic"))
                    # 强制生产端使用 view_topic（与消费者保持一致）
                    send_kafka_message(topic=kafka_topic or "view_topic", key=str(getattr(instance, 'id', "") or ""), value=view_log)
                except Exception as _e:
                    logger.error(f"发送课程浏览日志失败: {_e}")
                return Response({
                    "code":1,
                    "message":"查询成功",
                    "data":serializer.data
                })
            except Exception as e:
                logger.error(f"查询课程详情发生异常:{str(e)}")
                return Response({
                    "code":0,
                    "message":"查询失败"
                })

class CourseExpireAPIView(APIView):

    def get(self, request, *args, **kwargs):
        """
        请求参数:
            1:?course_ids=1,2,3,4  ?course_ids=1
        返回值:包括课程ID---》价格 ,有效期
        """
        try:

            # 从请求获取参数 1,2,3==>[1,2,3]
            course_ids = request.query_params.get("course_ids")
            logger.info(f"正在获取课程:{course_ids}的课程有效期信息")
            if not course_ids:
                return Response({
                    "code": 0,
                    "message": "参数错误:请提供课程ID"
                })
            course_id_list = [int(id) for id in course_ids.split(",")]
            logger.info(f"正在获取课程:{course_id_list}的课程有效期信息")

            # [1,2,3]
            if not course_id_list:
                return Response({
                    "code": 0,
                    "message": "格式错误"
                })

            coures = Course.objects.filter(
                id__in=course_id_list,
                is_deleted=False,
                status=1
            ).values("id", "name", "price")
            logger.info(f"查询到课程:{coures}")

            course_dict = {str(course['id']): course for course in coures}
            logger.info(f"课程:{course_dict}")

            expire_list = CourseExpire.objects.filter(
                course_id__in=course_id_list
            )
            logger.info(f"查询到课程有效期:{expire_list}")

            # 初始化最终数据的字典
            course_data = {}
            # [1,2,3]
            for expire in expire_list:
                course_id = str(expire.course_id)
                logger.info(f"正在处理课程:{course_id}")
                logger.info(course_data)

                # 如果这个课程还没有出现到course_data结果字典中, 初始化最外层的数据结构
                if course_id not in course_data:
                    course_data[course_id] = {
                        'name': expire.course.name,
                        "expire_list": []
                    }

                course_data[course_id]['expire_list'].append(
                    {
                        'expire_time': expire.expire_time,
                        'expire_text': f"{expire.expire_time}天" if expire.expire_time > 0 else "永久有效",
                        "price": float(expire.price)
                    }
                )
                logger.info(course_data)

            for course_id, course_info in course_dict.items():
                logger.info(course_id)
                logger.info(course_info)

                if course_id not in course_data:
                    logger.info(f"加默认值:{course_id}")
                    course_data[course_id] = {
                        'name': course_info['name'],
                        'expire_list': [
                            {
                                'expire_time': 0,
                                'expire_text': "永久有效",
                                'price': float(course_info['price'])
                            }

                        ]
                    }

            # 返回结果
            return Response({
                "code": 1,
                "message": "SUCCESS",
                "data": course_data
            })


        except Exception as e:
            logger.error(f"获取课程有效期信息发生异常:{str(e)}")
            return Response({
                "code": 0,
                "message": f"获取课程有效期信息失败:{str(e)}"
            })





class CourseContentAPIView(APIView):
    """课程内容接口"""
    permission_classes = [IsAuthenticated]

    def get(self, request):
        # 获取参数
        order_number = request.query_params.get('order_number')
        course_id = request.query_params.get('course_id')

        if not all([order_number, course_id]):
            return Response({
                'code': 0,
                'message': '参数不完整'
            })

        try:
            # 查询订单详情
            order_detail = OrderDetail.objects.select_related('order').get(
                order_number=order_number,
                course_id=course_id,
                order__user=request.user  # 确保是当前用户的订单
            )

            logger.info('订单详情：%s' % order_detail)

            # 检查订单状态
            if order_detail.order.order_status != 1:  # 1表示已支付
                return Response({
                    'code': 0,
                    'message': '订单未支付'
                })

            # 检查课程有效期
            if order_detail.expire_time and order_detail.expire_time < timezone.now():
                return Response({
                    'code': 0,
                    'message': '课程已过期'
                })

            # 获取课程章节和课时信息
            chapters = CourseChapter.objects.filter(
                course_id=course_id
            ).prefetch_related('lessons').order_by('number').distinct()

            logger.info('课程章节：%s' % chapters)

            # 序列化数据
            serializer = CourseChapterSerializer(chapters, many=True)

            return Response({
                'code': 1,
                'message': 'success',
                'data': serializer.data
            })

        except OrderDetail.DoesNotExist:
            return Response({
                'code': 0,
                'message': '未购买此课程'
            })
        except Exception as e:
            return Response({
                'code': 0,
                'message': '获取课程内容失败'
            })